package testing;

import org.apache.log4j.Logger;

import java.io.File;
import java.io.IOException;
import java.net.Socket;

/**
 * User: Luke Lamonica
 * This class is the main entry point for coordinating test operations and
 * the connections to client machine(s).
 */
public class Coordinator {
//TODO: add input reading thread to look for shutdown command, then gracefully shutdown processes on remote hosts

    private static volatile boolean shutdown = false;
    private static int pending;

    private Logger LOG = Logger.getLogger(Coordinator.class);

    public static void main(String[] args) {

        /* password refers to that associated with the user's private key */
        String password = args[0];

        /* Retrieve configuration data for tests */
        //TODO: change configFile to not be machine specific
        String configFile = "../simple-lookup-service-scalability-framework/src/main/java/testing/config.yaml";
        Configuration.configure(configFile);

        pending = Configuration.clientHosts.size();

        /* Try the sLS host to ensure it's accessible */
        try {
            System.out.println("Testing connection with sLS server...");
            Socket socket = new Socket(Configuration.slsServer, Configuration.port);

            System.out.println("Connected");
        } catch (IOException e) {

            System.out.println(e.getMessage());
            return;
        }

        /* Instantiating MessengerPool starts messenger threads that arrange
         * execution of the specified tests on the client machines */
        MessengerPool messengerPool = new MessengerPool(Configuration.username, Configuration.clientHosts, Configuration.workingDir, Configuration.resultRepo, Configuration.clientProgram, Configuration.sshKeyFile, password);

        /* Wait for the messenger threads to complete their runs */
        while (!shutdown && getPending() > 0) {

            synchronized (Coordinator.class) {

                try {

                    System.out.println("Waiting for messenger threads to finish work");
                    Coordinator.class.wait(3000);

                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        System.out.println("Disconnecting from hosts");
        messengerPool.disconnect();
        System.out.println("Disconnected");

        OutputWriter.print(Configuration.resultRepo);
    }

    /* Returns the number of active messenger threads */
    public static synchronized int getPending() {

        return pending;
    }

    /* Updates pending to indicate one less active messenger thread */
    public static synchronized void decrementPending() {

        if (--pending == 0) {

            setShutdownFlag(true);
        }
    }

    /* Signals the main thread to join messenger threads and finish the test */
    public static synchronized void setShutdownFlag(boolean value) {

        shutdown = value;
    }
}
